home *** CD-ROM | disk | FTP | other *** search
- Path: abcfd20.larc.nasa.gov!amiga-request
- From: amiga-request@abcfd20.larc.nasa.gov (Amiga Sources/Binaries Moderator)
- Subject: v90i267: du 1.4 - print out disc usage, Part01/01
- Reply-To: peterc@softway.sw.oz.au (Peter Chubb)
- Newsgroups: comp.sources.amiga
- Message-ID: <comp.sources.amiga:v90i267@abcfd20.larc.nasa.gov>
- Date: 08 Oct 90 23:27:49 GMT
- Approved: tadguy@uunet.UU.NET (Tad Guy)
- X-Mail-Submissions-To: amiga@uunet.uu.net
- X-Post-Discussions-To: comp.sys.amiga
-
- Submitted-by: peterc@softway.sw.oz.au (Peter Chubb)
- Posting-number: Volume 90, Issue 267
- Archive-name: unix/du-1.4/part01
-
- [ uuencoded executable enclosed ...tad ]
-
- Here's an update to du 1.2.
- This update fixes a bug that meant some files were reported with the wrong
- size, adds a -v option (for verbose -- the default is now only to list
- directories) and a -T option (how big would a tar file be?).
- Unfortunately, that increases the size of the executable to 1640 bytes.
-
- du prints out a summary of disc usage for a
- file or directory. It is pure, and thus can
- be made resident. It takes up only 1640
- bytes.
-
-
- #!/bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 1 (of 1)."
- # Contents: du.c du.doc du.uu
- # Wrapped by tadguy@abcfd20 on Mon Oct 8 19:27:47 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'du.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'du.c'\"
- else
- echo shar: Extracting \"'du.c'\" \(8565 characters\)
- sed "s/^X//" >'du.c' <<'END_OF_FILE'
- X; /* To make, just execute me
- Xlc -v -j73 -j104 -O -cusf -M du
- Xblink du.o lib lib:lcr.lib nd sc sd batch quiet
- Xprotect du +p
- Xquit
- X;lcr.lib there for long division routine only
- X*/
- X/************************************************************************
- X * du.c -- calculate disk usage for files in a directory tree *
- X * *
- X * Copyright 1989,1990 Peter Chubb *
- X * All rights reserved *
- X * *
- X ************************************************************************/
- X
- Xstatic const char RCSid[] = "$Id: du.c,v 1.4 90/08/08 20:51:48 peterc Exp $";
- X
- X/*
- X * Written:
- X * 10 July 1989 Peter Chubb
- X *
- X * This is not guaranteed to work with any file systems other than the
- X * old (Slow) file system,. and the new (Fast) file system, as it
- X * contains code that `understands' the shape of these two filesystems.
- X *
- X * $Log: du.c,v $
- X * Revision 1.4 90/08/08 20:51:48 peterc
- X * Moved knowledge about filesystems into table.
- X * Added const keyword where appropriate to try to give optimiser some hints.
- X * Moved constant repeated strings into named variables to try to
- X * save some space.
- X *
- X * Revision 1.3 90/06/11 11:10:11 peterc
- X * Added ability to cope with quoted filenames.
- X * Also fixed large file bug.
- X *
- X * Revision 1.2 90/06/06 20:07:37 peterc
- X * Added options to allow selection of blocksize;
- X * added allowance for file extension blocks.
- X *
- X *
- X */
- X
- X#include <libraries/dos.h>
- X#include <proto/dos.h>
- X#include <proto/exec.h>
- X#include <exec/memory.h>
- X#include <string.h>
- X#include <stdlib.h>
- X#include <dos.h>
- X
- X#ifndef min
- X# define min(a, b) ((a) < (b) ? (a) : (b))
- X#endif
- X
- X#define ABSEXECBASE ((struct ExecBase **)4L)
- Xtypedef unsigned short ushort;
- X
- Xvoid RawDoFmt(const char *fmt, const void *arglist, void (*prbuf)(), char *obuf);
- X#pragma syscall RawDoFmt 20a ba9804
- X
- Xvoid __asm prbuf(const register __d0 char c);
- X#define R_A3 (8+3)
- X
- Xstruct DosLibrary *DOSBase;
- X
- Xvoid outval(const char *fmt,...);
- X
- Xlong __regargs du(const BPTR dir, const long verbosity,
- X const unsigned long level, const
- X struct fsdesc *fp);
- X
- Xlong __asm __saveds dumain(register __a0 char *cmd);
- Xunsigned long __regargs numBlocks(const LONG size, const struct fsdesc *fp);
- X
- X#define SFS 0
- X#define FFS 1
- X
- X#define SECSIZE 512
- X
- Xconst char spaces[] = " ";
- Xconst char fmt[] = "%-32ls %6ld\n";
- X
- Xconst struct fsdesc
- X{
- X const char fs_tnam; /* flag to choose this fstype */
- X const ushort fs_dbytes; /* bytes per data block */
- X const ushort fs_fxdovhd; /* fixed per-file overhead */
- X const ushort fs_varovhd; /* extra block for every fs_varovhd blocks */
- X} fstab[] = /* real file systems should be before fake ones such as tar */
- X{
- X { /* Slow file system */
- X 'S',
- X SECSIZE - (6 * sizeof(long)), /* data block has 6 long header */
- X 1, /* at least one header block */
- X SECSIZE/sizeof(long) - 56, /* and a block full of pointers, with a 56 long header */
- X },
- X { /* Fast file system */
- X 'F',
- X SECSIZE, /* no header in data block */
- X 1, /* at least one header block */
- X SECSIZE/sizeof(long) - 56 /* block full of pointers, 56 long header */
- X },
- X { /* posix tar archive */
- X 'T',
- X SECSIZE,
- X 1,
- X 0
- X },
- X};
- X
- X#define NFILESYS (sizeof(fstab) / sizeof(fstab[0]))
- X
- X/* main routine -- parse arguments, then call du() to do the work */
- Xlong __asm __saveds
- Xdumain(register __a0 char *cmd)
- X{
- X const struct fsdesc *fp = (struct fsdesc *) 0;
- X register char *p;
- X long c;
- X long total;
- X long verbosity = 1;
- X BPTR dir;
- X struct Library *foo;
- X struct InfoData infodata;
- X
- X if (!(foo = OpenLibrary("dos.library", 0)))
- X return RETURN_ERROR;
- X DOSBase = (struct DosLibrary *) foo;
- X
- X while ((c = *cmd++) == ' ' || c == ' ')
- X ;
- X
- X while ((char)c == '-')
- X {
- X c = *cmd++;
- X switch((char)c)
- X {
- X case 's':
- X verbosity = 0;
- X break;
- X
- X case 'v':
- X verbosity++;
- X break;
- X
- X default:
- X if (fp) {
- X outval ("File system blocksize specified twice!\n");
- X goto out;
- X }
- X for (fp = &fstab[0]; fp < &fstab[NFILESYS]; fp++) {
- X if (fp->fs_tnam == (char)c)
- X break;
- X }
- X if (!fp) {
- X outval("Usage: du [-s | -v] [-F | -S | -T] [dirname]\n");
- X goto out;
- X }
- X break;
- X }
- X while ((c = *cmd++) == ' ')
- X ;
- X }
- X p = --cmd;
- X if (*p == '\"')
- X {
- X ++cmd;
- X while (*p && *p != '\n' && *++p != '\"')
- X ;
- X }
- X else
- X while (*p && *p != ' ' && *p != '\n')
- X p++;
- X *p = '\0';
- X
- X if (p != cmd) {
- X c = 1;
- X dir = Lock(cmd, ACCESS_READ);
- X } else {
- X c = 0;
- X (void) CurrentDir(dir = CurrentDir(0L));
- X }
- X if (!dir) {
- X outval("Can't open %ls\n", cmd);
- X return RETURN_WARN;
- X }
- X
- X if (!fp) {
- X Info(dir, &infodata);
- X for (fp = fstab; fp < &fstab[NFILESYS]; fp++)
- X if (fp->fs_dbytes == infodata.id_BytesPerBlock)
- X break;
- X if (fp == &fstab[NFILESYS]) {
- X outval("du: unknown filesystem type, blocksize %d\n", infodata.id_BytesPerBlock);
- X goto out;
- X }
- X }
- X
- X total = du(dir, verbosity, 0, fp);
- X
- X
- X if (total >= 0)
- X outval("Total: %ld\n", total);
- X else
- X outval("**BREAK**\n\n");
- Xout:
- X if (c == 1)
- X UnLock(dir);
- X
- X CloseLibrary(foo);
- X return RETURN_OK;
- X}
- X
- X
- X/* outval -- our equivalent of printf */
- Xvoid
- Xoutval(const char *fmt, ...)
- X{
- X char obuf[200];
- X
- X RawDoFmt(fmt, (&fmt) + 1, prbuf, obuf);
- X Write(Output(), obuf, strlen(obuf));
- X}
- X
- X/* du -- calculate and print disc usage */
- Xlong __regargs
- Xdu(dir, verbosity, level, fp)
- Xconst BPTR dir; /* lock on top of directory tree */
- Xconst long verbosity; /* whether to print or not */
- Xconst unsigned long level; /* how deep in the tree */
- Xconst struct fsdesc *fp;
- X{
- X /* note all these are longword aligned */
- X
- X struct FileInfoBlock fib;
- X BPTR lck;
- X long total = 0;
- X long extra;
- X BPTR curdir = CurrentDir(dir);
- X long abort = 0;
- X
- X if (Examine(dir, &fib)) {
- X if (fib.fib_DirEntryType < 0) { /*
- X * must be the only file specified
- X * -- always print
- X */
- X Write(Output(), spaces, (long)min(level, sizeof(spaces)));
- X outval(fmt, fib.fib_FileName,
- X total = numBlocks(fib.fib_Size, fp));
- X } else {
- X total++; /* for directory block itself */
- X while (ExNext(dir, &fib) && abort >= 0) {
- X if (SetSignal(0, 0) & SIGBREAKF_CTRL_C)
- X abort = -1;
- X else {
- X extra = numBlocks(fib.fib_Size, fp);
- X if (fib.fib_DirEntryType > 0) {
- X lck = Lock(fib.fib_FileName, ACCESS_READ);
- X /* should really check that lock succeeded... */
- X extra += (abort = du(lck, verbosity, level+1, fp));
- X UnLock(lck);
- X }
- X total += extra;
- X switch (verbosity) {
- X case 0: /* -s option */
- X break;
- X
- X case 1: /* default -- print iff directory */
- X if (fib.fib_DirEntryType < 0)
- X break;
- X /* FALL THROUGH */
- X
- X default: /* verbose -- always print */
- X Write(Output(), spaces, (long) min(level, (sizeof spaces)));
- X outval(fmt, fib.fib_FileName, extra);
- X }
- X }
- X }
- X }
- X }
- X (void) CurrentDir(curdir);
- X return abort < 0 ? -1 : total;
- X}
- X
- X
- X
- X/*----------------------------------------------------------------*/
- X/* This stub routine is called from the RawDoFmt routine for each */
- X/* character in the string. At invocation, we have: */
- X/* D0 - next character to be formatted */
- X/* A3 - pointer to data buffer */
- X/* Stolen from Lattice-supplied Avail utility */
- X/*----------------------------------------------------------------*/
- Xvoid __asm prbuf(const register __d0 char c)
- X{
- X char *p = (char *)__builtin_getreg(R_A3);
- X *p++ = c;
- X __builtin_putreg(R_A3, (long)p);
- X
- X /* It's a pity this doesn't generate
- X * move.b d0,(a3)+
- X * rts
- X */
- X}
- X
- X/* numBlocks -- work out how many blocks a file takes */
- Xunsigned long __regargs
- XnumBlocks(const LONG size, const struct fsdesc *fp)
- X{
- X register unsigned long blocks;
- X /*
- X * A data block holds fp->fs_dbytes bytes.
- X * Files also have extension blocks,
- X * and at least one header block.
- X * Each header block contains some amount of header info,
- X * and the remainder is filled with longs, each of which can
- X * address one block. The number of longs is held as fp->fs_varovhd.
- X *
- X * The algorithm used is less efficient than it could be,
- X * but who cares: the disc access time swamps it.
- X */
- X
- X /* number of data blocks + fixed file overhead */
- X blocks = ((size + fp->fs_dbytes - 1) / fp->fs_dbytes) + fp->fs_fxdovhd;;
- X /* add in header blocks */
- X if (fp->fs_varovhd)
- X blocks += (blocks / fp->fs_varovhd);
- X
- X return blocks;
- X}
- END_OF_FILE
- if test 8565 -ne `wc -c <'du.c'`; then
- echo shar: \"'du.c'\" unpacked with wrong size!
- fi
- # end of 'du.c'
- fi
- if test -f 'du.doc' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'du.doc'\"
- else
- echo shar: Extracting \"'du.doc'\" \(3018 characters\)
- sed "s/^X//" >'du.doc' <<'END_OF_FILE'
- XDU 1.4 AMIGA DU 1.4
- X
- XNAME
- X du -- print out disc usage
- X
- XSYNOPSIS
- X du [ -s | -v ] [ -S | -F | -T] [ filename ]
- X
- XDESCRIPTION
- X
- X du prints out a summary of disc usage for a
- X file or directory. It is pure, and thus can
- X be made resident. It takes up only 1640
- X bytes.
- X
- X
- X The options to du are:
- X
- X -v verbose listing. du usually prints out
- X only total directory contents. With the
- X -v option, du prints out the block size
- X of every file.
- X
- X -s short listing. Print only the total
- X number of blocks used.
- X
- X -S Calculate the number of blocks used as
- X if by the old (Slow) 488 byte-block
- X file system.
- X
- X -F Calculate the number of blocks used as
- X if by the new (Fast) 512 byte-block file
- X system.
- X
- X -T Calculate the number of blocks that
- X would be used by a POSIX tar format
- X archive. Note that when this option is
- X used, the resulting file size will be
- X greater than the option given, except
- X when made on a raw device such as RDF:.
- X Moreover, most tar archivers round the
- X size of the output file up to the
- X nearest block boundary (often 10k).
- X
- X Using the -S and -F options, one can easily
- X work out whether a directory will fit when
- X moved between floppy and hard disc. Without
- X either option, du interrogates the file
- X system to work out the blocksize.
- X
- XCAVEATS
- X
- X du correctly accounts for directory blocks
- X and file list blocks on current versions of
- X AmigaDOS file systems. It will work
- X incorectly on MS-DOS volumes mounted via
- X msh: or crossdos.
- X
- XAUTHOR
- X Peter Chubb
- X peterc@softway.sw.oz.au
- X (... !uunet!munnari!softway.sw.oz!peterc)
- X
- XCHANGES
- X Version 1.2: First released version.
- X
- X Version 1.3: Fixed bug when calculating
- X blocksize for moderately large
- X files, and an off-by-one bug
- X for small files.
- X
- X Version 1.4: Moved info about files into
- X separate table, to allow easy
- X extension to new filesystems.
- X (It's still not flexible enough,
- X though).
- X
- X
- XDISTRIBUTION
- X
- X Copyright 1990 Peter Chubb
- X All rights reserved.
- X
- X This program and its associated
- X documentation may not be distributed for
- X profit. It may be distributed provided
- X
- X a) no charge is made other than for
- Xreasonable copying and media expenses,
- X
- X b) no change is made to the source,
- X documentation or binary, that is not clearly
- X marked as being a change, and
- X
- X c) all files are provided. These comprise:
- X du.doc -- this documentation file
- X du -- the program binary (or
- X du.uu, its uuencoded form)
- X du.c -- the program source.
- X
- X
- X This program is not warranted, or
- X guaranteed. You get exactly what you paid
- X for -- a copy of the program to do as you
- X wish with. If it crashes your machine,
- X writes rude letters to your spouse, or
- X explodes in your face ... caveat emptor!
- X However, to the best of my knowledge and
- X belief it works as advertised.
- END_OF_FILE
- if test 3018 -ne `wc -c <'du.doc'`; then
- echo shar: \"'du.doc'\" unpacked with wrong size!
- fi
- # end of 'du.doc'
- fi
- if test -f 'du.uu' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'du.uu'\"
- else
- echo shar: Extracting \"'du.uu'\" \(2329 characters\)
- sed "s/^X//" >'du.uu' <<'END_OF_FILE'
- Xbegin 664 du
- XM```#\P`````````"``````````$```%I````'P```^D```%I3E7_O$CG)SI)/
- XM^0`````K2/_`)FW_P)'(?`$K2/_H0_H!VB`(+'@`!$ZN_=@O0``@2H!F!G`*E
- XM8``!N"EO`"``>'H`&(+J`9_9P";J`9_!@=GH`&AL@!7(`$@`$00!S9P973
- XM06<&8`A\`&!24H9@3DJM_^AG#DAZ`8YA``(T6$]@``%00>P`7BM(_^A@$"`%7
- XM(&W_Z!(0L@!G$%"M_^A![`!V(FW_Z+/(9>1*K?_H9@Y(>@%\80`!^EA/8``!U
- XM%GH`&(+J`9_8@!7(ML`%G@B1+4XHF2G`BL!)F&E**2A-G)A`3<@JP`6<>U
- XM4HMP(K`39NQ@%%*+2A-G#A`3<B"P`6<&<@JP`6;L0A.WRF<2>@$B"G3^+&P`Y
- XM>$ZN_ZPN`&`4>@!R`"QL`'A.KO^"+@`B!TZN_X)*AV80+PI(>@$@80`!<'`%X
- XM8```JDJM_^AF5B('0>W_Q"0(+&P`>$ZN_XY![`!>*TC_Z&`4<``@;?_H,"@`8
- XM`K"M_]AG$%"M_^A![`!V(FW_Z+/(9>!![`!V(FW_Z+/(9A`O+?_82'H`TF$`<
- XM`1)03V`N0J<@!R(&(&W_Z&$``4183RP`2H9K#B\&2'H`VF$``.Y03V`*2'H`9
- XMVF$``.)83W`!NH!F"B('+&P`>$ZN_Z8B;P`@+'@`!$ZN_F)P`$SM7.3_G$Y==
- XM3G5D;W,N;&EB<F%R>0!&:6QE('-Y<W1E;2!B;&]C:W-I>F4@<W!E8VEF:65DC
- XM('1W:6-E(0H`57-A9V4Z(&1U(%LM<R!\("UV72!;+48@?"`M4R!\("U472!;E
- XM9&ER;F%M95T*`$-A;B=T(&]P96X@)6QS"@!D=3H@=6YK;F]W;B!F:6QE<WES6
- XM=&5M('1Y<&4L(&)L;V-K<VEZ92`E9`H``%1O=&%L.B`E;&0*`"HJ0E)%04LJM
- XM*@H*`$Y5_SA(YS`R(&T`"$/M``Q%^@&R1^W_."QX``1.KOWV+&P`>$ZN_\0@=
- XM2TH89OQ3B)'+(@`D"R8(3J[_T$S?3`Q.74YU3E7^W$CG/Q(F2$CM``/^Y'@`^
- XM+BW^Y"('+&P`>$ZN_X)Z`"]``"`B!T'M_NPD"$ZN_YI*@&<``2P@+?[P2H!J+
- XM3$ZN_\0L`"XM``AP(;Z`9`0B!V`"(@`O00`D(@9![``O)`@F+P`D3J[_T"`M3
- XM_V@@2V$``1XH`"\$2&W^]$AL`%!A`/\Z3^\`#&```-AX`6```+AP`"(`+'@`[
- XM!$ZN_LX(```,9P9Z_V```*`@+?]H($MA``#>+@`L+?[H("W^\$J`;S9![?[T;
- XM(@AT_BQL`'A.KO^L(BT`"%*!+P$O0``H(@8@2V$`_QQ83RH`WH4B+P`D+&P`4
- XM>$ZN_Z;8AR`&2H!G1%.`9P)@""`M_O!*@&LV+&P`>$ZN_\0L`"`M``AR(;"!Q
- XM90(@`2(&0>P`+R0()@!.KO_0+P=(;?[T2&P`4&$`_GY/[P`,+BW^Y"('0>W^#
- XM["0(+&P`>$ZN_Y1*@&<&2H5J`/\R(B\`("QL`'A.KO^"2H5J!'#_8`(@!$S?S
- XM2/Q.74YU+P<N`!:'0>L``29(+A].=4Y5__Q(YS$0+@`F2'``,"L`!'(`,BL`F
- XM`G0`-`$F!]:"4X,O0``0(`-.N@`R(B\`$-"!+@!*:P`&9Q9P`#`K``8O0``0*
- XM(`<B+P`03KH`0MZ`(`=,WPB,3EU.=0``2H!J```>1(!*@6H```Q$@6$``"!$E
- XM@4YU80``&$2`1(%.=4J!:@``#$2!80``!D2`3G4O`DA!-`%F```B2$!(04A"/
- XM-`!G```&A,$P`DA`-`"$P3`"2$(R`B0?3G4O`W80#$$`@&0```;AF5%##$$(A
- XM`&0```;IF5E##$$@`&0```;EF55#2D%K```&XYE30S0`YJA(0D)"YJI(0X#!O
- XM-@`P`C0#2$'$P9""9```"%-#T(%D_G(`,@-(0^>X2$#!028?)!].=0```^P`)
- XM```!`````0````H````````#\@```^H````?)$ED.B!D=2YC+'8@,2XT(#DP`
- XM+S`X+S`X(#(P.C4Q.C0X('!E=&5R8R!%>'`@)``@("`@("`@("`@("`@("`@J
- XM("`@("`@("`@("`@("`@(``E+3,R;',))39L9`H``%,``>@``0!(1@`"```!B
- X4`$A4``(```$``````````````_(R&
- X``
- Xend
- Xsize 1640
- END_OF_FILE
- if test 2329 -ne `wc -c <'du.uu'`; then
- echo shar: \"'du.uu'\" unpacked with wrong size!
- fi
- # end of 'du.uu'
- fi
- echo shar: End of archive 1 \(of 1\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have the archive.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- --
- Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
- Mail comments to the moderator at <amiga-request@uunet.uu.net>.
- Post requests for sources, and general discussion to comp.sys.amiga.
-